﻿namespace net.zxteam.ZXLexer.Runtime
{
	using System;

	public class RuntimeLexer : ILexer
	{
		public class RuntimeLexerException : Exception
		{
			public readonly int StatePosition, ParsingPosition;

			public RuntimeLexerException(int statePosition, int parsingPosition)
			{
				this.StatePosition = statePosition;
				this.ParsingPosition = parsingPosition;
			}

			public override string ToString()
			{
				return base.ToString() + string.Format(": {0}/{1}", StatePosition, ParsingPosition);
			}
		}

		private readonly XSD.grammar _pegData;

		public RuntimeLexer(System.IO.Stream pegInput)
		{
			this._pegData = (XSD.grammar)Internal.PegXmlSerializer.Instance.Deserialize(pegInput);
		}

		public AST.Token Parse(string inputText)
		{
			using (var lexerSource = new Internal.LexerSourceTextReader(inputText))
			{
				Internal.RuntimeLexerImpl lexerImpl = new Internal.RuntimeLexerImpl(lexerSource);
				AST.Token token = this._pegData.Accept(lexerImpl);

				if (lexerSource.Peek() != -1)
					throw new RuntimeLexerException(lexerSource.Position, lexerSource.Position);

				return token;
			}
		}
	}
}
